package com.ys.arch.splitamount.algorithm.utils;

import org.apache.commons.collections4.CollectionUtils;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>@description:</>
 *
 * @author shuang.yang
 * @version 1.0
 * @create 2021/12/25/21:34
 */
public class LambdaOperateUtil {

    public static <T, U, R> List<R> convertMap2List(Map<T, U> map, BiFunction<T, U, R> convertFunction) {

        return CollectionUtils.emptyIfNull(map.entrySet())
                .stream()
                .map(ele -> {
                    T t = ele.getKey();
                    U u = ele.getValue();
                    return convertFunction.apply(t, u);
                })
                .collect(Collectors.toList());


    }

    public static <T, U, R> List<R> convertMap2ListAndSorted(Map<T, U> map, BiFunction<T, U, R> convertFunction, Comparator<? super R> comparator) {

        return CollectionUtils.emptyIfNull(map.entrySet())
                .stream()
                .map(ele -> {
                    T t = ele.getKey();
                    U u = ele.getValue();
                    return convertFunction.apply(t, u);
                })
                .sorted(comparator)
                .collect(Collectors.toList());


    }
    /**
     * 执行金额累加
     *
     * @param originalList
     * @param condition
     * @param filterCondition
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T, K> K accumulateListByCondition(Collection<T> originalList,
                                                     Function<T, K> condition,
                                                     Predicate<T> filterCondition,
                                                     K identity,
                                                     BinaryOperator<K> accumulator) {

        return CollectionUtils.emptyIfNull(originalList)
                .stream()
                .filter(ele -> {
                    if (Objects.isNull(filterCondition)) {
                        return true;
                    }
                    return filterCondition.test(ele);
                })
                .map(condition)
                .reduce(identity, accumulator);

    }

}
